#include <iostream>
#include <memory>
#include <mutex>

struct node
{
    int a;
    char b;
    node(const int &a, const char &b)
        : a(a), b(b) {}
};

// auto_ptr的特性管理权转移，被转移权利的auto_ptr对象如果进行操作则会报错，因为他所管理的指针已经被置空了！！！
template <class T>
class auto_ptr_my
{
public:
    auto_ptr_my(T *ptr = nullptr) : _ptr(ptr) {}

    T &operator*()
    {
        return *_ptr;
    }

    T *operator->()
    {
        return _ptr;
    }

    auto_ptr_my(auto_ptr_my<T> &now) : _ptr(now._ptr)
    {
        now._ptr = nullptr;
    }

    auto_ptr_my<T> &operator=(auto_ptr_my<T> &now)
    {
        if (this != &now)
        {
            delete _ptr;
            _ptr = now._ptr;
            now._ptr = nullptr;
        }
        return *this;
    }
    ~auto_ptr_my()
    {
        if (!_ptr)
            delete _ptr;
    }

private:
    T *_ptr;
};

// unique_ptr直接给你赋值运算符和拷贝构造给禁了！
template <class T>
class unique_ptr_my
{
public:
    unique_ptr_my(T *ptr) : _ptr(ptr) {}
    unique_ptr_my(const unique_ptr_my<T> &now) = delete;
    unique_ptr_my<T> &operator=(const unique_ptr_my<T> &now) = delete;
    T &operator*()
    {
        return *_ptr;
    }
    T *operator->()
    {
        return _ptr;
    }
    ~unique_ptr_my()
    {
        std::cout << "delete" << std::endl;
        delete _ptr;
    }

private:
    T *_ptr;
};

//share_ptr注意可赋值共同管理，计数，在于计数方面无线程安全问题，但是如果是对于同一块内存的管理会有内存安全问题。
template <class T>
class share_ptr_my
{
public:
    share_ptr_my(T *ptr = nullptr) : _ptr(ptr)
    {
        if (ptr)
            count++;
        _count = new int(1);
        _mutex = new std::mutex;
    }
    share_ptr_my(const share_ptr_my<T> &now)
        : _ptr(now._ptr),
    {
        AddRef();
    }

    share_ptr_my<T> &operator=(share_ptr_my<T> &now)
    {
        if (this != &now)
        {
            AddRef();
            _ptr = now._ptr;
            _count = now._count;
            SubRef();
        }
        return *this;
    }

    int use_count()
    {
        return *_count;
    }

    ~share_ptr_my()
    {

        SubRef();
    }
    T operator*()
    {
        return *_ptr;
    }
    T *operator->()
    {
        return _ptr;
    }

private:
    void AddRef()
    {
        _mutex.lock();
        ++(*_count);
        _mutex.unlock();
    }

    void SubRef()
    {
        _mutex.lock();
        bool flag = false;
        if (--(*_count) == 0)
        {
            if (_ptr)
            {
                delete _ptr;
                _ptr = nullptr;
            }
            delete _count;
            _count = nullptr;
            flag = true;
        }
        _mutex.unlock();
        if (flag == true)
        {
            delete _mutex;
        }
    }

private:
    int *_count;
    T *_ptr;
    std::mutex _mutex;
};

int main()
{
    unique_ptr_my<int> ptr(new int(10));
    std::cout << *ptr << std::endl;
    unique_ptr_my<node> ptr2(new node(20, 'a'));
    // unique_ptr_my<node> ptr3(ptr2);
    std::cout << ptr2->a << std::endl;
    std::cout << ptr2->b << std::endl;
    return 0;
}

namespace cl
{
	template<class T>
	class weak_ptr
	{
	public:
		weak_ptr()
			:_ptr(nullptr)
		{}
		weak_ptr(const shared_ptr<T>& sp)
			:_ptr(sp.get())
		{}
		weak_ptr& operator=(const shared_ptr<T>& sp)
		{
			_ptr = sp.get();
			return *this;
		}
		//可以像指针一样使用
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr; //管理的资源
	};
}
